package com.firesrc.mail.thread;

import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import jodd.db.DbThreadSession;
import jodd.db.oom.DbOomQuery;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import com.firesrc.bean.Record;
import com.firesrc.db.DBManager;
import com.firesrc.mail.search.SearchMailStrategy;
import com.firesrc.mail.search.SearchMailerFactory;
import com.firesrc.util.JsoupUtil;

public class SearchMailExecutor {
  private static final int NTHREADS = 10;
  private static final ExecutorService executor = Executors.newFixedThreadPool(NTHREADS);
  private CompletionService<Set<Record>> completionService = new ExecutorCompletionService<Set<Record>>(executor);
  private static ConcurrentHashMap<String, Integer> failkeywordMap = new ConcurrentHashMap<String, Integer>();

  public static void main(String[] args) throws IOException {
    SearchMailExecutor renderer = new SearchMailExecutor();
    Set<Record> searchMai = renderer.searchMail("关键词", "100");
    System.out.println("SearchMailExecutor.main()" + searchMai);
  }

  public Set<Record> searchMail(String keyword, String count) throws IOException {
    final List<String> urls = JsoupUtil.getBaiduUrlListFromKeyword(keyword, count);
    System.out.println("SearchMailExecutor() 关键字<" + keyword + "> 找到网址:" + urls.size());
    if (urls.size() <= 0) {
      Integer integer = failkeywordMap.get(keyword);
      DbThreadSession dbThreadSession;
      if (integer != null) {
        if (integer >= 3) {
          if (JsoupUtil.checkNetConnect()) {
            dbThreadSession = new DbThreadSession(DBManager.getPublicConnectionPool());// fixme  要抽取出来到service里面
            DbOomQuery q1 = new DbOomQuery("delete from keyword  where name='" + keyword + "'");
            q1.executeUpdate();
            dbThreadSession.closeSession();
            failkeywordMap.remove(keyword);
            System.err.println("LogMailObserver.fail() 移除了3次不能查找到的关键词:" + keyword);
            return new HashSet<Record>();
          }
        }
        failkeywordMap.put(keyword, integer + 1);
      } else {
        failkeywordMap.put(keyword, 1);
      }
    }

    for (final String url : urls) {
      completionService.submit(new CallableSearchTask(url, keyword));
      try {
        Thread.currentThread();
        Thread.sleep(200);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }

    Set<Record> recordSet = new HashSet<Record>();
    try {
      for (int t = 0, n = urls.size(); t < n; t++) {
        Future<Set<Record>> f = completionService.take();
        Set<Record> mailSet = f.get();
        recordSet.addAll(mailSet);
      }
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
    } catch (ExecutionException e) {
      System.out.println("SearchMailExecutor.searchMail() error");
    }
    return recordSet;
  }

  public boolean checkNetConnect() throws IOException {
    Document doc = Jsoup.connect("http://www.baidu.com").get();
    boolean b = doc != null;
    return b;
  }

  private final class CallableSearchTask implements Callable<Set<Record>> {
    private final String url;
    private final String keyword;

    private CallableSearchTask(String url, String keyword) {
      this.url = url;
      this.keyword = keyword;
    }

    public Set<Record> call() {
      SearchMailStrategy strategy = SearchMailerFactory.getSingleSearchMailer();
      Set<Record> setRecord = strategy.getRecordFromUrl(url, keyword);
      return setRecord;
    }
  }

  public void shutdown() {
    executor.shutdown();
  }
}
